package cn.com.pansky.util;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

public class HttpUtil {
	
	// boundary generator
	private static String genBoundary() {
		String valid = "abcdefghijklmnopqrstuvwxyz123456789";
		StringBuilder stringBuilder = new StringBuilder(
				"binghezhoukegenerated_must_be_random");
		Random random = new Random();
		for (int i = 0; i < 60; i++) {
			stringBuilder.append(valid.charAt(random.nextInt(valid.length())));
		}
		return stringBuilder.toString();
	}

	// enable all https host
	public static void enableAllHost() throws NoSuchAlgorithmException,
			KeyManagementException {
		// Create a trust manager that does not validate certificate chains
		TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
			public java.security.cert.X509Certificate[] getAcceptedIssuers() {
				return null;
			}
			public void checkClientTrusted(X509Certificate[] certs,
					String authType) {
			}
			public void checkServerTrusted(X509Certificate[] certs,
					String authType) {
			}
		} };

		// Install the all-trusting trust manager
		SSLContext sc = SSLContext.getInstance("SSL");
		sc.init(null, trustAllCerts, new java.security.SecureRandom());
		HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

		// Create all-trusting host name verifier
		HostnameVerifier allHostsValid = new HostnameVerifier() {
			public boolean verify(String hostname, SSLSession session) {
				return true;
			}
		};

		// Install the all-trusting host verifier
		HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
	}

	public static String post(String urlStr, Map<String, String> params, Map<String, String> files) throws IOException {

		String boundary = genBoundary();
		MultipartEntityBuilder builder = MultipartEntityBuilder.create();
		builder.addTextBody("api_key", LssConstant.API_KEY);
		builder.addTextBody("api_secret", LssConstant.API_SECRET);
		if (params != null) {
			for (Map.Entry<String, String> entry : params.entrySet()) {
				builder.addTextBody(entry.getKey(), entry.getValue());
			}

		}
		if (files != null) {
			for (Map.Entry<String, String> entry : files.entrySet()) {
				builder.addBinaryBody(entry.getKey(), new File(entry.getValue()));
			}

		}

		builder.setBoundary(boundary);
		HttpEntity entity = builder.build();

		DefaultHttpClient client = new DefaultHttpClient();
		HttpPost httppost = new HttpPost(urlStr);  
		
		//20120627 by ljyan add 设置HttpPost编码
		//client.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "gbk");
//		httppost.setHeader("Content-Type", "text/html; charset=GBK");
				
		try {  
            //Secure Protocol implementation.    
            SSLContext ctx = SSLContext.getInstance("SSL");  
            //Implementation of a trust manager for X509 certificates    
            X509TrustManager tm = new X509TrustManager() {  
  
                public void checkClientTrusted(X509Certificate[] xcs,  
                        String string) throws CertificateException {  
  
                }  
  
                public void checkServerTrusted(X509Certificate[] xcs,  
                        String string) throws CertificateException {  
                }  
  
                public X509Certificate[] getAcceptedIssuers() {  
                    return null;  
                }  
            };  
            ctx.init(null, new TrustManager[] { tm }, null);  
            SSLSocketFactory ssf = new SSLSocketFactory(ctx);  
            ClientConnectionManager ccm = client.getConnectionManager();  
            //register https protocol in httpclient's scheme registry    
            SchemeRegistry sr = ccm.getSchemeRegistry();  
            sr.register(new Scheme("https", 443, ssf));  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
		
		httppost.setEntity(entity);
		CloseableHttpResponse resp = client.execute(httppost);
		
		Header[] headers = resp.getAllHeaders();
		System.out.println(Arrays.toString(headers));
		
		System.out.println(resp.getStatusLine());
		
		return EntityUtils.toString(resp.getEntity(), "UTF-8");
		
		// send data to server
//		URL url = new URL(urlStr);
//		java.net.URL url = new java.net.URL(null, urlStr, new sun.net.www.protocol.https.Handler());
//		HttpURLConnection con = (HttpURLConnection) url.openConnection();
//		con.setDoInput(true);
//		con.setDoOutput(true);
//		con.setRequestMethod("POST");
//		con.addRequestProperty("Content-Type", "multipart/form-data;boundary="+ boundary);
//
//		OutputStream outputStream = con.getOutputStream();
//		entity.writeTo(outputStream);
//		outputStream.flush();
//		outputStream.close();
//
//		if(con instanceof HttpsURLConnection) {
//			HttpsURLConnection https = (HttpsURLConnection) con;
//			int retCode = https.getResponseCode();
//			
//			if(retCode >= 400) {
//				System.out.println("--------face++------>"+https.getContentEncoding());
//				InputStream in = https.getErrorStream();
//				String response = readFromStream(in);
//				in.close();
//				return response;
//			}
//		}
//
//		try {
//			InputStream inputStream = con.getInputStream();
//			String response = readFromStream(inputStream);
//			inputStream.close();
//			return response;
//		} catch (Exception e) {
//			e.printStackTrace();
//			InputStream errorStream = con.getErrorStream();
//			String errResponse = readFromStream(errorStream);
//			errorStream.close();
//			return errResponse;
//		}
	}

	
	
	private static String readInputStream(Charset charset, InputStream in)
			throws IOException {
		byte[] bytes = new byte[1024];
		int length = -1;
		ByteArrayOutputStream byteOutput= new ByteArrayOutputStream();
		while ((length = in.read(bytes)) != -1) {
			byteOutput.write(bytes, 0, length);
		}
		return new String(byteOutput.toByteArray(), charset);
	}
	private static String readFromStream(InputStream is) throws IOException {
		if (is == null)
			return null;
		BufferedReader bufferedReader = new BufferedReader(
				new InputStreamReader(is));
		String tmp;
		StringBuilder stringBuilder = new StringBuilder();
		while ((tmp = bufferedReader.readLine()) != null) {
			stringBuilder.append(tmp);
		}
		return stringBuilder.toString();

	}
	
	
	public static void main(String[] args) throws KeyManagementException, NoSuchAlgorithmException, IOException {
		Map<String, String> files = new HashMap<String, String>();
		Map<String, String> params = new HashMap<String, String>();
		files.put("image", "/Users/xiangli/Desktop/temp/1.JPG");
		// 1.调用远程接口
		HttpUtil.enableAllHost();
		String result = HttpUtil.post(LssConstant.FACE_URL_IDCARD, params, files);
		System.out.println(result);
	}
}
